문서의 임의 삭제는 제재 대상으로, 문서를 삭제하려면 삭제 토론을 진행해야 합니다. 문서 보기문서 삭제토론 참조에 의한 호출 (문단 편집) == 예시 == 다음과 같은 [[C언어]] 코드가 있다고 하자. (기본적으로 맨 첫 줄에 #include 가 쓰여있다고 가정) {{{#!syntax cpp void functionA(int v) { v++; } int main(void) { int a = 10; functionA(a); printf("%d", a); } }}} > 결과값: 10 이와 같이 짜여진 함수는 main 함수 내의 변수 a의 값을 functionA에서 바꿀 수 없다. functionA의 스택 프레임에는 변수 a가 없기 때문이다. 하지만 [[C++]]에서 다음과 같이 작성한다면(기본적으로 맨 첫줄에 #include 이 쓰여있다고 가정) {{{#!syntax cpp void functionB(int& v) { v++; } int main(void) { int a = 10; functionB(a); printf("%d", a); } }}} > 결과값: 11 이렇게 하면 각 함수의 스택 프레임은 각기 따로 생기지만, main 함수의 변수 a를 '''참조'''하여 functionB에서 변경할 수 있다. 스택 프레임을 깨뜨리고 그냥 프로세스에 할당된 메모리 맵 전체를 대상으로 절대 주소 참조를 하기 때문이다. 좀 더 쉽게 말하면 functionB는 main 함수가 메모리를 어떻게 사용하고 있는지 전혀 모르지만 main 함수가 사용하고 있는 메모리 공간에 '''직접 좌표를 찍어서''' 강제로 값을 변경하는 것이다. 좌표를 찍는 것이기 때문에 좌표를 강제로 옮겨 버리면 엉뚱한 값을 바꾸게 된다. 예를 들어 {{{#!syntax cpp void functionC(int& v) { (*(&v+1))++; } int main(void) { int a = 10; int b = 1; functionC(a); printf("%d, %d", a, b); } }}} > 결과값: 10, 2 매개변수에 a를 전달했는데도 불구하고 엉뚱하게 b의 값이 변경되었다! main 함수의 a가 가진 주소 값에 1을 더한 위치에 b가 있었던 것이다. 거기에 증가 연산(++)을 하니 결국 b의 값이 늘어난 것. 참조에 의한 호출이 '''좌표를 찍는''' 방식이라는 건 바로 이것을 의미한다. 여기서 변수 b를 선언하는 부분을 빼고(printf 부분도 a만 출력하게 다듬고) 컴파일하면 컴파일러는 아무 경고 없이 컴파일을 하지만 실행하면 '''stack smashing detected'''라는 에러 메시지를 띄우며(리눅스 커널 4.4.0, [[g++]] 컴파일러 5.4.0 버전 기준) 프로그램이 강제 종료된다. 버퍼 오버플로우와 비슷한 상황인데 데이터 영역을 벗어나 코드 영역에 쓰기를 시도해서 OS가 프로그램 실행을 강제로 중지한 것이다. [[컴파일러]]는 코드에 무슨 이상이 있는지 감지하지 못해서 컴파일을 통과시켰지만 메모리 관리를 총괄하는 [[운영체제|OS]]가 메모리의 부정 접근을 탐지, 또는 [[CPU]]가 쓰기 금지된 메모리 페이지에 쓰기 시도(코드 영역은 컴파일러가 쓰기 금지 상태로 메모리에 적재되도록 만든다)를 감지해서 프로그램을 강제종료시킨 것. 참고로 [[운영체제|OS]]는 프로세스마다 완전히 격리된 가상 메모리 공간을 할당하므로, OS한테 특별히 요청해서 [[세마포어]]를 할당받지 않는 한 아무리 좌표를 찍으려 해도 '''다른 프로세스'''의 메모리까지는 건드리지 못한다.[* 하지만 같은 프로세스의 다른 스레드는 건드릴 수 있다. 일반적으로 부모자식 간이 아닌 스레드 사이에서 메모리 직접 참조가 발생하면 버그다. 하지만 당장 에러가 나진 않고 나중에 엉뚱한 지점에서 폭발한다. 프로그래머의 주적.]저장 버튼을 클릭하면 당신이 기여한 내용을 CC-BY-NC-SA 2.0 KR으로 배포하고,기여한 문서에 대한 하이퍼링크나 URL을 이용하여 저작자 표시를 하는 것으로 충분하다는 데 동의하는 것입니다.이 동의는 철회할 수 없습니다.캡챠저장미리보기